package com.five.esearch.impl;

import com.alibaba.fastjson.JSON;
import com.five.dto.NovelEsDTO;
import com.five.esearch.INovelDataSyncService;
import com.five.mapper.NovelMapper;
import com.five.pojo.Novel;
import com.five.util.NovelIndexInitializer;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 使用DTO的适配 6.8.6 数据同步服务
 */
@Service
public class NovelDataSyncServiceImpl  implements INovelDataSyncService {
    private static final String JDBC_URL = "jdbc:mysql://114.55.145.78:3306/ddchinesenovel?useSSL=false";
    private static final String JDBC_USER = "root";
    private static final String JDBC_PWD = "root";
    // 定义日期格式化器
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private final RestHighLevelClient esClient;

    public NovelDataSyncServiceImpl(RestHighLevelClient esClient) {
        this.esClient = esClient;
    }
    @Override
    public void syncSingleNovel(Novel novel) throws IOException {
        // 1. 将单条Novel转换为ES DTO
        NovelEsDTO dto = convertToEsDto(novel); // 新增单条转换方法

        // 2. 构建ES索引请求（单条插入）
        String json = JSON.toJSONString(dto);
        IndexRequest indexRequest = new IndexRequest(
                NovelIndexInitializer.INDEX_NAME,
                NovelIndexInitializer.TYPE_NAME,
                dto.getId().toString() // 用小说ID作为ES文档ID
        );
        indexRequest.source(json, XContentType.JSON);

        // 3. 执行单条插入
        esClient.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println("单条数据同步到ES成功：小说ID=" + novel.getId());
    }

    /**
     * 提取单条数据转换逻辑（复用，避免与批量转换重复）
     */
    @Override
    public NovelEsDTO convertToEsDto(Novel novel) {
        NovelEsDTO dto = new NovelEsDTO();
        dto.setId(novel.getId());
        dto.setBookTitle(novel.getTitle());
        // 查询作者名和分类名（复用原有逻辑）
        String authorName = novelMapper.selectAuthorById(novel.getAuthorId());
        dto.setAuthorName(authorName);
        String categoryName = novelMapper.selectCategoryById(novel.getCategoryId());
        dto.setCategoryName(categoryName);
        // 简介处理
        String intro = novel.getIntro();
        if (intro != null && intro.length() > 200) {
            intro = intro.substring(0, 200) + "...";
        }
        dto.setIntroduction(intro);
        // 其他字段映射
        dto.setStatus(novel.getStatus());
        dto.setScore(novel.getScore());
        dto.setWordCount(novel.getWordCount());
        // 1. 格式化 LocalDateTime 为字符串
        String createTimeStr = novel.getCreateTime().format(DATE_FORMATTER);
        // 2. 将字符串解析回 LocalDateTime
        LocalDateTime parsedCreateTime = LocalDateTime.parse(createTimeStr, DATE_FORMATTER);
        // 3. 设置到 DTO
        dto.setCreateTime(parsedCreateTime);

        // updateTime 同理
        String updateTimeStr = novel.getUpdateTime().format(DATE_FORMATTER);
        LocalDateTime parsedUpdateTime = LocalDateTime.parse(updateTimeStr, DATE_FORMATTER);
        dto.setUpdateTime(parsedUpdateTime);
        return dto;
    }

    @Override
    public void fullSync() throws Exception {
        // 1. 从MySQL查询实体类
        List<Novel> mysqlNovels = queryNovelsFromMysql();
        if (mysqlNovels.isEmpty()) {
            System.out.println("无数据需要同步");
            return;
        }

        // 2. 转换为ES专用DTO（核心：实体类 → DTO）
        List<NovelEsDTO> esDtos = convertToEsDtos(mysqlNovels);

        // 3. 同步DTO到ES
        BulkRequest bulkRequest = new BulkRequest();
        for (NovelEsDTO dto : esDtos) {
            String json = JSON.toJSONString(dto); // 序列化DTO为JSON
            IndexRequest indexRequest = new IndexRequest(
                    NovelIndexInitializer.INDEX_NAME,
                    NovelIndexInitializer.TYPE_NAME,
                    dto.getId().toString() // 用DTO的ID作为文档ID
            );
            indexRequest.source(json, XContentType.JSON);
            bulkRequest.add(indexRequest);
        }

        BulkResponse response = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        if (response.hasFailures()) {
            throw new RuntimeException("同步失败：" + response.buildFailureMessage());
        }
        System.out.println("同步完成，共 " + esDtos.size() + " 条数据");
    }

    /**
     * 转换MySQL实体类到ES DTO（可在此处添加数据处理逻辑）
     */
    @Autowired
    private NovelMapper novelMapper;
    @Override
    public List<NovelEsDTO> convertToEsDtos(List<Novel> mysqlNovels) {
        List<NovelEsDTO> dtos = new ArrayList<>();
        for (Novel novel : mysqlNovels) {
            dtos.add(convertToEsDto(novel)); // 调用单条转换方法
            NovelEsDTO dto = new NovelEsDTO();
            // 基础字段映射
            dto.setId(novel.getId());
            dto.setBookTitle(novel.getTitle());
            //映射作者名
            //调用mapper查询作者名@todo
            String AuthorName = novelMapper.selectAuthorById( novel.getAuthorId());
            dto.setAuthorName(AuthorName);
            String categoryName = novelMapper.selectCategoryById(novel.getCategoryId());
            dto.setCategoryName(categoryName);

            // 示例：对简介做截断处理（ES不需要过长的文本）
            String intro = novel.getIntro();
            if (intro != null && intro.length() > 200) {
                intro = intro.substring(0, 200) + "...";
            }
            dto.setIntroduction(intro);
            // 其他字段映射
            dto.setStatus(novel.getStatus());
            dto.setScore(novel.getScore());
            dto.setWordCount(novel.getWordCount());
            dto.setCreateTime(novel.getCreateTime());
            dto.setUpdateTime(novel.getUpdateTime());
            dtos.add(dto);

        }
        return dtos;
    }

    /**
     * 从MySQL查询实体类（仅负责数据库交互）
     */
    public List<Novel> queryNovelsFromMysql() throws Exception {
        List<Novel> result = new ArrayList<>();
        try (Connection conn = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PWD);
             PreparedStatement ps = conn.prepareStatement("SELECT * FROM t_novel");
             ResultSet rs = ps.executeQuery()) {
            while (rs.next()) {
                Novel novel = new Novel();
                novel.setId(rs.getLong("id"));
                novel.setTitle(rs.getString("title"));
                novel.setAuthorId(rs.getLong("author_id"));
                novel.setCategoryId(rs.getLong("category_id"));
                novel.setIntro(rs.getString("intro"));
                novel.setStatus(rs.getByte("status"));
                novel.setScore(rs.getDouble("score"));
                novel.setWordCount(rs.getLong("word_count"));
                novel.setCreateTime(rs.getTimestamp("create_time").toLocalDateTime());
                novel.setUpdateTime(rs.getTimestamp("update_time").toLocalDateTime());
                result.add(novel);
            }
        }
        return result;
    }
}